package com.kurt.controller;

import com.kurt.annotation.Log;
import com.kurt.common.PageResult;
import com.kurt.common.Result;
import com.kurt.dto.OrganizationDTO;
import com.kurt.dto.create.OrganizationCreateRequest;
import com.kurt.dto.query.OrganizationQueryRequest;
import com.kurt.dto.update.OrganizationUpdateRequest;
import com.kurt.service.OrganizationService;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 组织管理控制器
 * 提供组织相关的REST API接口
 */
@Slf4j
@RestController
@RequestMapping("/organizations")
@RequiredArgsConstructor
public class OrganizationController extends BaseController {

    private final OrganizationService organizationService;

    /**
     * 创建组织
     *
     * @param createRequest 创建请求
     * @return 创建结果
     */
    @Log(title = "创建组织", businessType = 1)
    @PostMapping
    public Result<OrganizationDTO> createOrganization(@Valid @RequestBody OrganizationCreateRequest createRequest) {
        try {
            log.info("创建组织请求: {}", createRequest.getName());
            OrganizationDTO organization = organizationService.createOrganization(createRequest);
            return Result.success("组织创建成功", organization);
        } catch (Exception e) {
            log.error("创建组织失败", e);
            return Result.error("创建组织失败: " + e.getMessage());
        }
    }

    /**
     * 更新组织
     *
     * @param updateRequest 更新请求
     * @return 更新结果
     */
    @Log(title = "更新组织", businessType = 2)
    @PutMapping
    public Result<OrganizationDTO> updateOrganization(@Valid @RequestBody OrganizationUpdateRequest updateRequest) {
        try {
            log.info("更新组织请求: {}", updateRequest.getId());
            OrganizationDTO organization = organizationService.updateOrganization(updateRequest);
            return Result.success("组织更新成功", organization);
        } catch (Exception e) {
            log.error("更新组织失败", e);
            return Result.error("更新组织失败: " + e.getMessage());
        }
    }

    /**
     * 根据ID获取组织详情
     *
     * @param id 组织ID
     * @return 组织详情
     */
    @GetMapping("/{id}")
    public Result<OrganizationDTO> getOrganizationById(@PathVariable("id") Long id) {
        try {
            log.info("获取组织详情请求: {}", id);
            OrganizationDTO organization = organizationService.getOrganizationById(id);
            return Result.success("获取组织详情成功", organization);
        } catch (Exception e) {
            log.error("获取组织详情失败", e);
            return Result.error("获取组织详情失败: " + e.getMessage());
        }
    }

    /**
     * 分页查询组织
     *
     * @param queryRequest 查询请求
     * @return 分页结果
     */
    @PostMapping("/page")
    public Result<PageResult<OrganizationDTO>> getOrganizationPage(@RequestBody OrganizationQueryRequest queryRequest) {
        try {
            log.info("分页查询组织请求: {}", queryRequest);
            Page<OrganizationDTO> page = organizationService.getOrganizationPage(queryRequest);
            PageResult<OrganizationDTO> pageResult = PageResult.of(
                    page.getNumber() + 1,
                    page.getSize(),
                    page.getTotalElements(),
                    page.getContent()
            );
            return Result.success("分页查询组织成功", pageResult);
        } catch (Exception e) {
            log.error("分页查询组织失败", e);
            return Result.error("分页查询组织失败: " + e.getMessage());
        }
    }

    /**
     * 查询组织列表
     *
     * @param queryRequest 查询请求
     * @return 组织列表
     */
    @PostMapping("/list")
    public Result<List<OrganizationDTO>> getOrganizationList(@RequestBody OrganizationQueryRequest queryRequest) {
        try {
            log.info("查询组织列表请求: {}", queryRequest);
            List<OrganizationDTO> organizations = organizationService.getOrganizationList(queryRequest);
            return Result.success("查询组织列表成功", organizations);
        } catch (Exception e) {
            log.error("查询组织列表失败", e);
            return Result.error("查询组织列表失败: " + e.getMessage());
        }
    }

    /**
     * 删除组织
     *
     * @param id 组织ID
     * @return 删除结果
     */
    @Log(title = "删除组织", businessType = 3)
    @DeleteMapping("/{id}")
    public Result<Boolean> deleteOrganization(@PathVariable("id") Long id) {
        try {
            log.info("删除组织请求: {}", id);
            boolean success = organizationService.deleteOrganization(id);
            return Result.success("组织删除成功", success);
        } catch (Exception e) {
            log.error("删除组织失败", e);
            return Result.error("删除组织失败: " + e.getMessage());
        }
    }

    /**
     * 批量删除组织
     *
     * @param ids 组织ID列表
     * @return 删除结果
     */
    @Log(title = "批量删除组织", businessType = 3)
    @DeleteMapping("/batch")
    public Result<Boolean> deleteOrganizations(@RequestBody List<Long> ids) {
        try {
            log.info("批量删除组织请求: {}", ids);
            boolean success = organizationService.deleteOrganizations(ids);
            return Result.success("批量删除组织成功", success);
        } catch (Exception e) {
            log.error("批量删除组织失败", e);
            return Result.error("批量删除组织失败: " + e.getMessage());
        }
    }

    /**
     * 获取组织树
     *
     * @param parentId 父组织ID
     * @return 组织树
     */
    @GetMapping("/tree")
    public Result<List<OrganizationDTO>> getOrganizationTree(@RequestParam(required = false) Long parentId) {
        try {
            log.info("获取组织树请求: parentId={}", parentId);
            List<OrganizationDTO> tree = organizationService.getOrganizationTree(parentId);
            return Result.success("获取组织树成功", tree);
        } catch (Exception e) {
            log.error("获取组织树失败", e);
            return Result.error("获取组织树失败: " + e.getMessage());
        }
    }

    /**
     * 获取所有组织树
     *
     * @return 组织树
     */
    @GetMapping("/tree/all")
    public Result<List<OrganizationDTO>> getAllOrganizationTree() {
        try {
            log.info("获取所有组织树请求");
            List<OrganizationDTO> tree = organizationService.getAllOrganizationTree();
            return Result.success("获取所有组织树成功", tree);
        } catch (Exception e) {
            log.error("获取所有组织树失败", e);
            return Result.error("获取所有组织树失败: " + e.getMessage());
        }
    }

    /**
     * 根据父组织ID获取子组织列表
     *
     * @param parentId 父组织ID
     * @return 子组织列表
     */
    @GetMapping("/children/{parentId}")
    public Result<List<OrganizationDTO>> getChildrenByParentId(@PathVariable("parentId") Long parentId) {
        try {
            log.info("获取子组织列表请求: parentId={}", parentId);
            List<OrganizationDTO> children = organizationService.getChildrenByParentId(parentId);
            return Result.success("获取子组织列表成功", children);
        } catch (Exception e) {
            log.error("获取子组织列表失败", e);
            return Result.error("获取子组织列表失败: " + e.getMessage());
        }
    }

    /**
     * 检查组织名称是否存在
     *
     * @param name 组织名称
     * @return 是否存在
     */
    @GetMapping("/exists/name/{name}")
    public Result<Boolean> existsByName(@PathVariable("name") String name) {
        try {
            log.info("检查组织名称是否存在请求: {}", name);
            boolean exists = organizationService.existsByName(name);
            return Result.success("检查组织名称是否存在成功", exists);
        } catch (Exception e) {
            log.error("检查组织名称是否存在失败", e);
            return Result.error("检查组织名称是否存在失败: " + e.getMessage());
        }
    }

    /**
     * 移动组织到新的父组织下
     *
     * @param id          组织ID
     * @param newParentId 新父组织ID
     * @return 移动结果
     */
    @Log(title = "移动组织到新的父组织下", businessType = 3)
    @PostMapping("/{id}/move")
    public Result<Boolean> moveOrganization(@PathVariable("id") Long id, @RequestParam Long newParentId) {
        try {
            log.info("移动组织请求: id={}, newParentId={}", id, newParentId);
            boolean success = organizationService.moveOrganization(id, newParentId);
            return Result.success("组织移动成功", success);
        } catch (Exception e) {
            log.error("移动组织失败", e);
            return Result.error("移动组织失败: " + e.getMessage());
        }
    }

    /**
     * 更新组织排序
     *
     * @param id        组织ID
     * @param sortOrder 排序号
     * @return 更新结果
     */
    @Log(title = "更新组织排序", businessType = 3)
    @PostMapping("/{id}/sort")
    public Result<Boolean> updateSortOrder(@PathVariable("id") Long id, @RequestParam Integer sortOrder) {
        try {
            log.info("更新组织排序请求: id={}, sortOrder={}", id, sortOrder);
            boolean success = organizationService.updateSortOrder(id, sortOrder);
            return Result.success("组织排序更新成功", success);
        } catch (Exception e) {
            log.error("更新组织排序失败", e);
            return Result.error("更新组织排序失败: " + e.getMessage());
        }
    }
}
